
package main.java.util;


import main.java.Column;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

public class BeanUtil {

    private static final Map<Class<?>,Object> primitiveDefaults = new HashMap<Class<?>,Object>();


    /**
     * 当数据库取出null值时,给基本数据类型默认值
     */
    static {
        primitiveDefaults.put(Integer.TYPE,Integer.valueOf(0));
        primitiveDefaults.put(Short.TYPE,Short.valueOf((short)0));
        primitiveDefaults.put(Byte.TYPE,Byte.valueOf((byte)0));
        primitiveDefaults.put(Float.TYPE,Float.valueOf(0f));
        primitiveDefaults.put(Double.TYPE,Double.valueOf(0d));
        primitiveDefaults.put(Long.TYPE,Long.valueOf(0L));
        primitiveDefaults.put(Boolean.TYPE,Boolean.FALSE);
        primitiveDefaults.put(Character.TYPE,Character.valueOf((char)0));
    }


    public static Object creatBean(ResultSet rs,Class<?> type) throws SQLException{
        try {
            Object bean = type.newInstance();
            //获取数据库表结构信息，比如字段数、字段名等
            ResultSetMetaData metaData = rs.getMetaData();
            for (int i=1;i<=metaData.getColumnCount();i++){
                //getColumnName查出的是原本表中的字段名
                //getColumnLabel查出的是咱们在后面重新定义测字段名
                /**
                 * getColumnName返回的是sql语句中field的原始名字。
                 getColumnLabel是field的SQL AS的值（Alias--别名）
                 */
                String columnLabel = metaData.getColumnLabel(i);
                setProperty(columnLabel,type,rs,bean);
            }
            return bean;
        } catch (Exception e) {
            e.printStackTrace();
            throw new SQLException(e.getMessage());
        }

    }

    private static void setProperty(String columnLabel,Class<?> type,ResultSet rs,Object bean) throws Exception{
        //创建Bean实例
        BeanInfo beanInfo = Introspector.getBeanInfo(type, Object.class);
        //PropertyDescriptor[]获得元对象Bean的所有属性和属性的值
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

        for (PropertyDescriptor pd:propertyDescriptors){
            type = pd.getReadMethod().getDeclaringClass();
            String fieldName = pd.getName();
            Field field = type.getDeclaredField(fieldName);
            if(field.isAnnotationPresent(Column.class)){
                fieldName = field.getAnnotation(Column.class).value();
            }else {
                fieldName = fieldName;
            }

            if (fieldName.equalsIgnoreCase(columnLabel)){
                Object value = ColumnUtil.columnConvert(rs,columnLabel,pd.getPropertyType());
                if(value == null&&pd.getPropertyType().isPrimitive()){
                    value = primitiveDefaults.get(pd.getPropertyType());
                }
                pd.getWriteMethod().invoke(bean,value);
                break;
            }

        }
    }

    public static void main(String[] args) {
        System.out.println(primitiveDefaults.get(Float.TYPE));
    }
}
